package com.unnamed.collisions.editor;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import com.unnamed.collisions.geometry.Polygon;

public class PolygonViewer {
	
	List<Polygon> polygons;
	List<Polygon> selection;
	int width, height;
	int gridSize;
	int zoom;
	
	Point position;
	Point cursor;
	Point origin;
	
	
	
	public PolygonViewer(){
		position = new Point(10,10);
		cursor = new Point(10,10);
		origin = new Point(0,0);
		zoom = 1;
		gridSize = 20;
	
		polygons = new ArrayList<Polygon>();
		
		selection = new ArrayList<Polygon>();
		
	}
	
	public void resize(int width, int height){
		this.width=width;
		this.height=height;
	}
	
	public int getGridSize() {
		return gridSize;
	}

	public void setGridSize(int gridSize) {
		this.gridSize = gridSize;
	}

	public int getZoom() {
		return zoom;
	}

	public void setZoom(int zoom) {
		this.zoom = zoom;
	}

	public Point getPosition() {
		return position;
	}

	public void setPosition(Point position) {
		this.position = position;
	}

	public Point getCursor() {
		return cursor;
	}

	public void setCursor(Point cursor) {
		this.cursor = cursor;
	}
	
	public void setOrigin(Point origin){
		this.origin = origin;
	}
	
	public Point getOrigin(){
		return origin;
	}

	private void drawCursor(Graphics2D g){
		g.setColor(Color.cyan);
		g.drawRect(cursor.x, cursor.y, 10, 10);
		//g.drawRect(position.x,position.y, 10, 10);
		
		
		g.setColor(Color.white);
		
//		g.drawLine(-position.x, -position.y+cursor.y,-position.x+ width,-position.y+cursor.y );
//		g.drawLine(-position.x+cursor.x, -position.y,-position.x+cursor.x,-position.y+height);
		g.drawLine(-position.x,cursor.y,-position.x+width,cursor.y);
		g.drawLine(cursor.x,-position.y,cursor.x,-position.y+height);
	}
	
	private void clear(Graphics2D g){
		g.setBackground(Color.black);
		g.clearRect(-position.x, -position.y,width,height);
	}
	
	private void drawPolygons(Graphics2D g){
		for(Polygon p : polygons){
			com.unnamed.collisions.geometry.Point[] points = p.getTxPoints();
			int length = points.length;
			
			if(selection.contains(p)){
				g.setColor(Color.white);
				g.setStroke(new BasicStroke());
			}else{
				g.setColor(Color.cyan);
				g.setStroke(new BasicStroke(1.5f, 2, 2));
			}
			
			for(int c = 0;c<length;c++){
				com.unnamed.collisions.geometry.Point a = points[c%length];
				com.unnamed.collisions.geometry.Point b = points[(c+1)%length];
				
				g.drawLine((int)a.getX(),(int)a.getY(),(int)b.getX(),(int)b.getY());
				g.setColor(Color.green);
				g.drawRect((int)p.getCenter().getX()-5, (int)p.getCenter().getY()-5, 10, 10);
				float radius = p.getRadius();
				g.drawArc((int)(p.getCenter().getX()-radius), (int)(p.getCenter().getY()-radius), (int)p.getRadius()*2,(int)p.getRadius()*2, 0, 360);
				g.setColor(Color.pink);
				g.drawRect((int)p.getMassCenter().getX()-5, (int)p.getMassCenter().getY()-5, 10,10);
			}
		}
	}
	
	public void drawGrid(Graphics2D g){
		g.setColor(new Color(.2f,.2f,.2f));

		for(int x = -width;x<width;x+=gridSize){
			g.drawLine(x, -position.y, x, -position.y+height);
		}
		
		for(int y = -height;y<height;y+=gridSize){
			g.drawLine(-position.x,y,-position.x+width,y);
		}
		g.setColor(Color.green);	
		// Position
		g.drawRect(-gridSize/2,-gridSize/2, gridSize,gridSize);
		// Shape origin
		g.drawArc(origin.x-gridSize/2, origin.y-gridSize/2, gridSize, gridSize, 0, 360);
		
		g.setColor(Color.blue);
		g.drawRect(-width/2,-height/2, width, height);
	}
	
	public void draw(Graphics2D g){
		g.setTransform(getTransform());
		clear(g);
		drawGrid(g);
		drawPolygons(g);
		drawCursor(g);
			
//		try {
//			g.getTransform().rotate(.1f);
//			TexturePaint tp = new TexturePaint(ImageIO.read(new File("d:/3D/textures/123456.png")), new Rectangle(10, 10));
//			g.setPaint(tp);
//			AffineTransform at=new AffineTransform();
//			at.translate(50, 50);
//			at.rotate(.5f);
//			at.scale(5, 5);
//			g.setTransform(at);
//			g.fillRect(0, 0, 100, 100);
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
	}
	
	
	private AffineTransform getTransform(){
		AffineTransform tx = new AffineTransform();
		tx.scale(zoom, zoom);
		tx.translate(position.x, position.y);
		return tx;
	}
	
	public void addPolygon(Polygon p){
		this.polygons.add(p);
	}
	
	public Point getPanelSpace(Point p){
		Point2D dst = new Point2D.Float();
		try {
			getTransform().inverseTransform(p, dst);
		} catch (NoninvertibleTransformException e) {
			// TODO Auto-generated catch block
			return p;
		}
		return new Point((int)dst.getX(),(int)dst.getY());
	}

	/**
	 * Establece el poligono mas cercano al punto elegido
	 * como seleccionado
	 * @param panelSpace
	 */
	public void selectPolygonAt(Point point) {
		Polygon s = null;
		for(Polygon p:polygons){
			if(s==null){
				s=p;
			}
			
			if(p.getCenter().distance(new com.unnamed.collisions.geometry.Point(point.x,point.y))<s.getCenter().distance(new com.unnamed.collisions.geometry.Point(point.x,point.y))){
				s=p;
			}
		}
		
		if(s!=null){
			if(selection.contains(s)){
				selection.remove(s);
			}else{
				selection.add(s);
			}
		}
	}
}
